package com.wzdigit.wms.wms.service.wms2oms;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.common.entity.CommonProperty;
import com.wzdigit.wms.wms.client.web.service.wms2oms.sync.ctnr.OmsStkServicePortTypeProxy;
import com.wzdigit.wms.wms.client.web.service.wms2oms.sync.ctnr.Req_Pl;
import com.wzdigit.wms.wms.client.web.service.wms2oms.sync.ctnr.Rsp_Pl;
import com.wzdigit.wms.wms.service.mid.IfPostbackService;
import com.wzdigit.wms.wms.strategy.webservice.iservice.ISendWebService;
import com.wzdigit.wms.wms.strategy.webservice.type.SendWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @version 1.0
 * @desc WMS TO OMS实际装柜清单接口
 * @Author:yangwenbiao
 * @Date 2021/2/2 3:55 PM
 */
@Slf4j
@Service
@SendWebService(value = TopicEnum.TOPIC_OMS_ACTUAL_CTNR, name = "实际装柜清单接口")
public class SyncPackListService implements ISendWebService {

    @Autowired
    IfPostbackService ifPostbackService;

    @Value("${oms.web.service.protocol-head}")
    private String protocolHead;

    @Value("${oms.web.service.url}")
    private String url;

    @Value("${wzdigit.web.service.oms.ip}")
    private String ip;


    private static final String SOURCE = "WMS";
    private static final String DESTINATION = "OMS";

    /**
     * 调OMS的【实际装柜清单接口】
     *
     * @param oqcInsp
     * @param count
     * @return
     */
//    private ZDT_003_RspRecordHead[] getReportResult(OqcInsp oqcInsp, Integer count) throws RestStatusException {
//        ZDT_003_RspRecordHead[] record;
//        try {
////            record = report();
//        } catch (Exception e) {
//            e.printStackTrace();
//
//            String msg = StatusCode.SAP_REPORT_CHECK_ERROR.message();
//            RestStatusException exception = new RestStatusException(msg);
//            exception.setContent(msg);
//            throw exception;
//        }
////        return record;
//        return null;
//    }

    /**
     * 定时任务调用SAP的【交货单接口】
     *
     * @return
     */
    public Rsp_Pl[] report(Req_Pl[] reqPls) throws Exception {
        log.info("开始调用OMS系统【实际装柜清单接口】》》》》》》》》》》》》》》》》》》》》》》》");
        //发送【向SAP报检】的路径
        String urlString = protocolHead + ip + url;

        log.info("发送报文的路径:" + urlString);

        OmsStkServicePortTypeProxy proxy = new OmsStkServicePortTypeProxy();

        proxy.setEndpoint(urlString);

//TODO 下面注释掉
        //请求参数
//        Req_Pl reqPl = new Req_Pl();
//
//        reqPl.setAttribute1("1");
//        reqPl.setAttribute2("2");
//        reqPl.setAttribute3("3");
//        reqPl.setAttribute4("4");
//        reqPl.setAttribute5("5");
//        reqPl.setAttribute6("6");
//        reqPl.setAttribute7("7");
//        reqPl.setAttribute8("8");
//        reqPl.setAttribute9("9");
//        reqPl.setAttribute10("10");
//
//        reqPl.setOms_Notice_No("33");
//        reqPl.setWms_Flag("33");
//        reqPl.setSer(1);
//        reqPl.setCabno("33");
//        reqPl.setOms_Notice_Item(110);
//        reqPl.setSap_So_No("33");
//        reqPl.setSap_So_Item(112);
//        reqPl.setItem_Code("33");
//        reqPl.setCabtype("33");
//        reqPl.setSealno("33");
//        reqPl.setCarno("33");
//        reqPl.setCarbinno("33");
//        reqPl.setFactqty(new BigDecimal(222));
//        reqPl.setQty(new BigDecimal(1));
//        reqPl.setNote("咩啊啊啊啊啊啊啊啊啊啊啊啊");

//TODO 上面注释掉

//        Req_Pl[] reqPls = new Req_Pl[1];
//        reqPls[0] = reqPl;


        //输出请求的核心报文
        try {
            for (Req_Pl pl : reqPls) {
                //打印报文信息
//                printXml(pl, Class.forName("com.wzdigit.wms.wms.client.web.service.wms2oms.sync.ctnr.Req_Pl"));
                printXml(pl, pl.getClass(), CommonProperty.COMMON_TRUE);
            }

        } catch (JAXBException e) {
            e.printStackTrace();
            log.error("转成XML出错");
            throw new RuntimeException("转成XML出错");
        }


        Rsp_Pl[] rspPls = null;

        try {
            //发送报文
            rspPls = proxy.syncPackList(reqPls);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("OMS系统接口异常" + e.getMessage());
        }
        if (rspPls == null) {
            throw new RuntimeException("OMS系统接口异常，返回NULL");
        }
//        } catch (RemoteException e) {
//            e.printStackTrace();
//        }

        for (Rsp_Pl rspPl : rspPls) {
            //打印返回报文的日志
            try {
                printXml(rspPl, Class.forName("com.wzdigit.wms.wms.client.web.service.wms2oms.sync.ctnr.Rsp_Pl"), CommonProperty.COMMON_FALSE);
            } catch (JAXBException e) {
                e.printStackTrace();
                throw new RuntimeException("格式化异常" + e.getMessage());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException("格式化异常" + e.getMessage());
            }
        }

        return rspPls;
    }

    /**
     * 答应XML报文
     *
     * @param o
     * @param tClass
     * @param
     * @throws JAXBException
     */
    private void printXml(Object o, Class<?> tClass, Integer flag) throws JAXBException {
        //格式化生成的XML报文
        JAXBContext jc = JAXBContext.newInstance(tClass);
        Marshaller ms = jc.createMarshaller();
        ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        Writer writer = new StringWriter();
        ms.marshal(o, writer);

        if (flag == 1) {
            log.info("发送报文的核心内容【xml】:" + writer.toString());
        } else {
            log.info("响应报文的核心内容【xml】:" + writer.toString());
        }
    }


    @Deprecated
    public <T> T getObject(Class<T> c) throws IllegalAccessException, InstantiationException {
        T t = c.newInstance();

        System.out.println(t);
        return t;
    }


    /**
     * 格式化日期，8位
     *
     * @param
     * @return
     */
    public String getDateStr() {
        Date now = new Date();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateStr = formatter.format(now);
        return dateStr;
    }


    /**
     * 获得当前时间时分秒
     *
     * @return
     */
    private String getTimeStr() {
        Date now = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("HHmmss");
        String timeStr = formatter.format(now);
        return timeStr;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Object send(Object object) {

        IfPostback postback = new IfPostback();

        //构建数据
        IfPostback ifPostback = (IfPostback) object;
        String postbackContent = ifPostback.getPostbackContent();
        Req_Pl[] reqPls = JSON.parseObject(postbackContent, new TypeReference<Req_Pl[]>() {});


        //回参的JSON
        String returnJson = new String();
        //系统异常标识
        boolean flag = false;

        Rsp_Pl[] report = null;
        String errMsg = new String();
        //TODO 测试代码，测试和投产记得删除
//        int a = 0 / 0;
        try {
//            Rsp_Pl[] report = report(reqPls);
            report = report(reqPls);
            //回写表
            returnJson = JSON.toJSONString(report);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("调OMS实际装柜清单接口异常，日志打印三次");
            log.error("调OMS实际装柜清单接口异常，日志打印三次");
            log.error("调OMS实际装柜清单接口异常，日志打印三次");
            //发生异常，更新标识
            flag = true;
            errMsg = e.getMessage();

        } finally {

            if (flag) {
                //调接口异常，解析异常等
                postback.setIfPostbackId(ifPostback.getIfPostbackId());
                postback.setPostbackTime(new Date());
                postback.setPostbackResult(BackResultEnum.SYSTEM_ERROR_STATE.getCode());
                postback.setReturnMessage(errMsg);

                Integer row = ifPostbackService.updateOne(postback);
                log.info("成功更新{}条记录", row);
            } else {
                postback.setIfPostbackId(ifPostback.getIfPostbackId());
                postback.setPostbackTime(new Date());
                postback.setReturnMessage(returnJson);
                postback.setPostbackResult(BackResultEnum.BUSINESS_SUCCESS_STATE.getCode());

                for (Rsp_Pl rsp_pl : report) {
                    if (!rsp_pl.getData_Success().equals(true)) {
                        postback.setPostbackResult(BackResultEnum.BUSINESS_FAIL_STATE.getCode());
                    }
                }

                Integer row = ifPostbackService.updateOne(postback);
                log.info("成功更新{}条记录", row);
            }
        }


        return postback;
    }
}
